import axios from 'axios'
import {getToken, removeToken, setToken} from '@/utils/auth'
import router from '@/router/index'
// import {useRoute} from 'vue-router'

// create an axios instance
const instance = axios.create({
  // url = base url + request url
  baseURL: eval('`' + process.env.VUE_APP_BASE_API + '`'),
  // set backend protocol version
  headers: {
    version: 'v1'
  },
  // request timeout
  timeout: 5000
})

// request interceptor
instance.interceptors.request.use(
  config => {
    // 让每一个请求携带自定义token
    const token = getToken()
    console.log('请求拦截中设置携带的token', token)
    if (token) {
      config.headers['Authorization'] = 'Bearer ' + token['access_token']
    }
    return config
  },
  error => {
    console.log('请求拦截器异常信息：', error)
    return Promise.reject(error)
  }
)

// // response interceptor
// instance.interceptors.response.use(response => {
//   // console.log('响应拦截器正常信息：', response)
//   return response.data
// })

function refreshToken(refresh_token) {
  return instance.post('/api/token/refresh/', {
    refresh: refresh_token
  })
}

function errorHandler(error, responseError = null, noResponseError = null, requestError = null) {
  const response = error.response
  const request = error.request
  const message = error.message
  // const config = error.config
  if (response) {
    // The request was made and the server responded with a status code
    // that falls out of the range of 2xx
    if (responseError) {
      return responseError(response)
    } else {
      throw response
    }
  } else if (request) {
    // The request was made but no response was received
    // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
    // http.ClientRequest in node.js
    if (noResponseError) {
      return noResponseError(request)
    } else {
      throw {
        message: "网络连接异常！"
      }
    }
  } else {
    // Something happened in setting up the request that triggered an Error
    if (requestError) {
      return requestError(message)
    } else {
      throw {
        message: "请求异常！"
      }
    }
  }
}

function request(config) {
  return new Promise((resolve, reject) => {
    instance(config)
      .then(response => {
        console.log('请求成功：', response.data)
        return resolve(response.data)
      })
      .catch(error => {
        try {
          errorHandler(error, response => {
            const token = getToken()
            if (token && (response.status === 401)) {
              refreshToken(token['refresh_token'])
                .then(refreshResponse => {
                  const token = refreshResponse.data.data
                  console.log('获取新token', token)
                  setToken(token)
                  // 携带新的token重新发起请求
                  const oldConfig = response.config
                  const newConfig = {
                    url: oldConfig.url,
                    method: oldConfig.method,
                    data: JSON.parse(oldConfig.data)
                  }
                  console.log('再次发起请求，配置：', newConfig)
                  instance(newConfig)
                    .then(response => {
                      return resolve(response.data)
                    })
                    .catch(error => {
                      // 此处内的异常在Promise中，无法向上传递，需在内部进行捕获处理
                      try {
                        errorHandler(error)
                      } catch (error) {
                        console.log('请求失败：', error.data)
                        reject(error.data)
                      }
                    })
                })
                .catch(error => {
                  // 刷新token失败，神仙也救不了了
                  // 此处内的异常在Promise中，无法向上传递，需在内部进行捕获处理
                  try {
                    errorHandler(error)
                  } catch (error) {
                    removeToken()
                    console.log('刷新token失败：', error)
                    router.push({
                      name: 'login',
                      query: {
                        redirect: router.currentRoute.value.fullPath
                      }
                    }).then()
                    reject({
                      message: '用户认证失效，请重新登陆！'
                    })
                  }
                })
            } else {
              throw response.data
            }
          })
        }
        catch (error) {
          console.log('请求失败：', error)
          reject(error)
        }
      })
  })
}

export default request

